package sk.stancel.peter.lastsmsfree.widget;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.RemoteViews;

import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import sk.stancel.peter.lastsmsfree.R;
import sk.stancel.peter.lastsmsfree.SmsInfo;


/**
 * Implementation of App Widget functionality.
 */
public class LastSMSWidget extends AppWidgetProvider {

    private static final String ADDRESS = "address";
    private static final String BODY = "body";
    private static final String DATE = "date";

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        // There may be multiple widgets active, so update all of them
        for (int i = 0; i < appWidgetIds.length; i++) {
            updateAppWidget(context, appWidgetManager, appWidgetIds[i]);
        }
    }

    private void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
        updateAppWidget(context, appWidgetManager, appWidgetId, null);
    }

    private void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId, SmsInfo smsInfo) {

        RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.last_sms_widget);

        if(smsInfo == null) {
            String[] projection = {ADDRESS, BODY, DATE};
            Cursor cursor = context.getContentResolver().query(Uri.parse("content://sms/inbox"), projection, null, null, "date desc limit 1");

            if (cursor != null && cursor.moveToFirst()) {
                smsInfo = new SmsInfo();

                smsInfo.setMsisdn(cursor.getString(0));
                smsInfo.setBody(cursor.getString(1));
                smsInfo.setDate(cursor.getLong(2));

                cursor.close();
            }else{
                remoteViews.setTextViewText(R.id.widget_text, context.getString(R.string.no_sms));
            }
        }

        if (smsInfo != null){
            smsInfo.setContactName(getContactName(context, smsInfo.getMsisdn()));

            Log.i("LAST_SMS_FREE", smsInfo.getMsisdn() + " " + smsInfo.getBody() + " " + smsInfo.getContactName() + " " + smsInfo.getDate());

            if(smsInfo.getContactName() != null && !smsInfo.getContactName().isEmpty()){
                remoteViews.setTextViewText(R.id.widget_number, smsInfo.getContactName());
            }else {
                remoteViews.setTextViewText(R.id.widget_number, smsInfo.getMsisdn());
            }

            DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.getDefault());
            remoteViews.setTextViewText(R.id.widget_time, dateFormat.format(new Date(smsInfo.getDate())));

            remoteViews.setTextViewText(R.id.widget_text, smsInfo.getBody());

            Intent smsIntent = new Intent(Intent.ACTION_VIEW);
            smsIntent.setData(Uri.parse("sms:" + smsInfo.getMsisdn()));

            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, smsIntent, 0);
            remoteViews.setOnClickPendingIntent(R.id.widget_layout, pendingIntent);
        }

        appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
    }

    private String getContactName(Context context, String msisdn) {
        Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(msisdn));
        String name = null;

        Cursor contactLookup = context.getContentResolver().query(uri, new String[] {ContactsContract.PhoneLookup.DISPLAY_NAME }, null, null, null);

        if(contactLookup != null && contactLookup.moveToFirst()){
            name = contactLookup.getString(0);
            contactLookup.close();
        }
        return name;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {

            SmsInfo smsInfo = null;

            Bundle bundle = intent.getExtras();
            if (bundle != null) {
                smsInfo = new SmsInfo();
                // get information about sms
                Object[] pdus = (Object[]) bundle.get("pdus");
                final SmsMessage[] messages = new SmsMessage[pdus.length];
                // sms is long so it is split into pieces - messages
                for (int i = 0; i < pdus.length; i++) {
                    messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
                }
                if (messages.length > -1) {
                    smsInfo.setMsisdn(messages[0].getOriginatingAddress());

                    Calendar calendar = Calendar.getInstance();
                    smsInfo.setDate(calendar.getTimeInMillis());

                    StringBuilder text = new StringBuilder();
                    // merge all sms parts
                    for (int i = 0; i < messages.length; i++) {
                        text.append(messages[i].getMessageBody());
                    }
                    smsInfo.setBody(text.toString());
                }
            }

            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context.getApplicationContext());
            ComponentName thisWidget = new ComponentName(context.getApplicationContext(), LastSMSWidget.class);
            int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
            if (appWidgetIds != null && appWidgetIds.length > 0) {
                for (int i = 0; i < appWidgetIds.length; i++) {
                    updateAppWidget(context, appWidgetManager, appWidgetIds[i], smsInfo);
                }
            }
        }else{
            super.onReceive(context, intent);
        }
    }
}
